﻿using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media.Animation;
using BusinessIntelligenceToolkit.Controls.ContainerGenerators;

namespace BusinessIntelligenceToolkit.Controls
{
    [TemplatePart(Name = ScrollViewerPart, Type = typeof(BitScrollViewer))]
    public class BitItemsControl : Control
    {
        public static readonly DependencyProperty ItemsSourceProperty =
            DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(BitItemsControl), new PropertyMetadata(OnItemsSourceChanged));

        public static readonly DependencyProperty ItemTemplateProperty =
            DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(BitItemsControl), new PropertyMetadata(default(DataTemplate)));

        public static readonly DependencyProperty CurrentPositionProperty =
            DependencyProperty.Register("CurrentPosition", typeof(double), typeof(BitItemsControl), new PropertyMetadata(OnCurrentPositionChanged));

        public static readonly DependencyProperty CollectionViewProperty =
            DependencyProperty.Register("CollectionView", typeof(ICollectionView), typeof(BitItemsControl), new PropertyMetadata(default(ICollectionView)));

        public static readonly DependencyProperty ContainerGeneratorProperty =
            DependencyProperty.Register("ContainerGenerator", typeof(IContainerGenerator), typeof(BitItemsControl), new PropertyMetadata(default(IContainerGenerator)));

        public static readonly DependencyProperty AnimationProperty =
            DependencyProperty.Register("Animation", typeof(DoubleAnimation), typeof(BitItemsControl), new PropertyMetadata(default(DoubleAnimation)));

        internal readonly HashSet<object> SelectedItems = new HashSet<object>();

        private const string ScrollViewerPart = "PART_ScrollViewer";

        static BitItemsControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(BitItemsControl), new FrameworkPropertyMetadata(typeof(BitItemsControl)));
        }

        public BitItemsControl()
        {
            Initialized += (s, e) => CreateContainerGenerator();
            Loaded += (s, e) =>
                          {
                              ApplyTemplate();
                          };
        }

        public DoubleAnimation Animation
        {
            get { return (DoubleAnimation)GetValue(AnimationProperty); }
            set { SetValue(AnimationProperty, value); }
        }

        public IEnumerable ItemsSource
        {
            get { return (IEnumerable)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }

        public DataTemplate ItemTemplate
        {
            get { return (DataTemplate)GetValue(ItemTemplateProperty); }
            set { SetValue(ItemTemplateProperty, value); }
        }

        public double CurrentPosition
        {
            get { return (double)GetValue(CurrentPositionProperty); }
            set { SetValue(CurrentPositionProperty, value); }
        }

        public ICollectionView CollectionView
        {
            get { return (ICollectionView)GetValue(CollectionViewProperty); }
            set { SetValue(CollectionViewProperty, value); }
        }

        public IContainerGenerator ContainerGenerator
        {
            get { return (IContainerGenerator)GetValue(ContainerGeneratorProperty); }
            set { SetValue(ContainerGeneratorProperty, value); }
        }

        internal IEnumerable<ContentPresenter> Containers
        {
            get { return CustomScrollViewer.Containers.Cast<ContentPresenter>().ToList(); }
        }
        
        protected BitScrollViewer CustomScrollViewer { get; set; }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            CustomScrollViewer = (BitScrollViewer)GetTemplateChild(ScrollViewerPart);
        }

        protected virtual void CreateContainerGenerator()
        {
            ContainerGenerator = new BitItemsControlContainerGenerator(this);
        }

        protected virtual void OnCollectionViewChanging(ICollectionView oldCollectionView, ICollectionView newCollectionView)
        {
        }

        private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            BitItemsControl instance = d as BitItemsControl;

            if (instance.ItemsSource is ListCollectionView)
            {
                var collectionView = instance.ItemsSource as ListCollectionView;
                instance.OnCollectionViewChanging(instance.CollectionView, collectionView);
                instance.CollectionView = collectionView;
            }
            else
            {
                var collectionView = new ListCollectionView(instance.ItemsSource.Cast<object>().ToList());
                instance.OnCollectionViewChanging(instance.CollectionView, collectionView);
                instance.CollectionView = collectionView;
            }
        }

        private static void OnCurrentPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            BitItemsControl instance = d as BitItemsControl;
            instance.CustomScrollViewer.CurrentPosition = instance.CurrentPosition;
        }
    }
}